import { Tabs } from '@aws-amplify/ui-react';
import { ExampleCode } from '@/components/Example';
import Liveness from './liveness-service-setup.mdx';
import CognitoCallout from './cognito-callout.mdx';
import CLI from './quick-start-pull-cli.mdx';
import QuickAddSwift from './quick-start-add.swift.mdx';
import Credentials from './credentials-provider-callout.mdx';

There are four methods to setup the Amazon Cognito resources needed for Amplify Auth. The most common is the Amplify CLI create flow which asks a series of questions and will configure both a User Pool and Identity Pool automatically. The second option is the Amplify CLI import flow which adds an existing Cognito resource into Amplify. The third is to reuse or create a Cognito Identity Pool manually and to add it into your application. Finally the fourth is to pass a credentials provider which obtains the AWS credentials under your control.

<CognitoCallout />

<Tabs.Container defaultValue="Amplify CLI">
  <Tabs.List>
    <Tabs.Item value="Amplify CLI">Amplify CLI</Tabs.Item>
    <Tabs.Item value="Existing Cognito Resource">Existing Cognito Resource</Tabs.Item>
    <Tabs.Item value="Self Managed Cognito Resource">Self Managed Cognito Resource</Tabs.Item>
    <Tabs.Item value="Custom Credentials Provider">Custom Credentials Provider</Tabs.Item>
  </Tabs.List>
  <Tabs.Panel value="Amplify CLI">
> Use the Amplify CLI to automatically configure and manage your Cognito Identity and User Pool for you.

FaceLivenessDetector uses Amplify Auth by default to authorize users to perform the Face Liveness check. If you are using Amplify for the first time, follow the instructions for [installing the Amplify CLI](https://docs.amplify.aws/cli/start/install/).

#### Set up a new Amplify project

```bash
$ amplify init
? Enter a name for the project swiftliveness
? Initialize the project with the above configuration? No
? Enter a name for the environment dev
? Choose your default editor: Xcode (macOS only)
? Choose the type of app that you're building ios
```

<CLI />

#### Push to create the resources

```bash
$ amplify push
✔ Successfully pulled backend environment dev from the cloud.

Current Environment: dev

| Category | Resource name    | Operation | Provider plugin   |
| -------- | ---------------- | --------- | ----------------- |
| Auth     | swiftlive••••••• | Create    | awscloudformation | 
```

_If you have an existing backend, run `amplify pull` to sync your `amplifyconfiguration.json` with your cloud backend._

You should now have an `amplifyconfiguration.json` file in your `app/src/main/res/raw` directory with your latest backend configuration.
  <QuickAddSwift />
  </Tabs.Panel>
  <Tabs.Panel value="Existing Cognito Resource">
> If you previously had unmanaged resources that you want to manage with Amplify you can use the CLI to import your Cognito resources.

FaceLivenessDetector uses Amplify Auth by default to authorize users to perform the Face Liveness check. Follow the instructions for [importing existing resources](https://docs.amplify.aws/lib/auth/getting-started/q/platform/android/#set-up-backend-resources).
 <QuickAddSwift />
  </Tabs.Panel>
  <Tabs.Panel value="Self Managed Cognito Resource">
> Use this option if you already have a Cognito identity/user pools that you do not want to import to Amplify, or want to manage Cognito resources yourself or with a 3rd party resource management tool.

If you already have Cognito set up or do not want to use the Amplify CLI to generate Cognito resources, you can follow the documentation in the [existing resources tab](https://docs.amplify.aws/lib/auth/getting-started/q/platform/android/#set-up-backend-resources).

_If you are manually setting up an identity pool in the Cognito console you can follow [this guide](https://docs.aws.amazon.com/cognito/latest/developerguide/getting-started-with-identity-pools.html#create-identity-pool). When setting up the identity pool ensure that access to unauthenticated identities is enabled._

When initially configuring Amplify (assuming you are using no pieces of Amplify other than the FaceLivenessDetector) you can manually create an `amplifyconfiguration.json` and add it your project’s main directory in this form:

```json
{
  "auth": {
    "plugins": {
      "awsCognitoAuthPlugin": {
        "CredentialsProvider": {
          "CognitoIdentity": {
            "Default": {
              "PoolId": "us-east-1:-------------",
              "Region": "us-east-1"
            }
          }
        }
      }
    }
  }
}
```
<QuickAddSwift />
  </Tabs.Panel>
  <Tabs.Panel value="Custom Credentials Provider">
> Use this option if you want more control over the process of obtaining AWS credentials.

By default, FaceLivenessDetector uses Amplify Auth to authorize users to perform the Face Liveness check. You can use your own credentials provider to retrieve credentials from [Amazon Cognito](https://aws.amazon.com/cognito/) or assume a role with [Amazon STS](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html), for example:

For long lived credentials, you may retrieve `AWSCredentials` by implementing your custom `AWSCredentialsProvider`.

```swift
/**
 Represents AWS credentials.

 Typically refers to long-term credentials that do not expire unless manually rotated or deactivated.
 These credentials are generally associated with an IAM (Identity and Access Management) user and are used to authenticate API requests to AWS services.

 - Properties:
 - accessKeyId: A unique identifier.
 - secretAccessKey: A secret key used to sign requests cryptographically.
 */

public protocol AWSCredentials {

    /// A unique identifier.
    var accessKeyId: String { get }

    /// A secret key used to sign requests cryptographically.
    var secretAccessKey: String { get }
}
```

```swift
import Amplify

struct MyCredentialsProvider: AWSCredentialsProvider {
    func fetchAWSCredentials() async throws -> AWSCredentials { 
        // Return `AWSCredentials` object instance
    }
}
```

If you're providing temporary credentials, make sure that your `AWSCredentials` object conforms to `AWSTemporaryCredentials`, which must include `sessionToken`.

```swift
/**
 Represents temporary AWS credentials.

 Refers to short-term credentials generated by AWS STS (Security Token Service).
 These credentials are used for temporary access, often for applications, temporary roles, federated users, or scenarios requiring limited-time access.

 - Inherits: AWSCredentials

 - Properties:
 - sessionToken: A token that is required when using temporary security credentials to sign requests.
 - expiration: The expiration date and time of the temporary credentials.
 */
public protocol AWSTemporaryCredentials: AWSCredentials {

    /// A token that is required when using temporary security credentials to sign requests.
    var sessionToken: String { get }

    /// The expiration date and time of the temporary credentials.
    var expiration: Date { get }
}
```

```swift
import Amplify

struct MyCredentialsProvider: AWSCredentialsProvider {
    func fetchAWSCredentials() async throws -> AWSCredentials { 
        // Return `AWSTemporaryCredentials` object instance
    }
}
```


```swift
import SwiftUI
import FaceLiveness

struct MyView: View { 
  @State private var isPresentingLiveness = true

  var body: some View { 
    FaceLivenessDetectorView(
      sessionID: <session ID>,
      region: <region>,
      credentialsProvider: MyCredentialsProvider(),
      isPresented: $isPresentingLiveness,
      onCompletion: { result in
        switch result {
        case .success: 
          // ...
        case .failure(let error):
          // ...
        default:
          // ...
        }
      }
    )
  }
}
```

<Credentials />
<Liveness />

### Step 2. Install dependencies

In Xcode, navigate to **File > Add Packages...**
Enter the **Amplify UI Swift Liveness** GitHub repo URL (`https://github.com/aws-amplify/amplify-ui-swift-liveness`) into the search bar and hit **Enter**. Wait for the result to load.

You'll see the **Amplify UI Swift Liveness** repository rules for which version of Liveness you want Swift Package Manager to install. Choose the dependency rule **Up to Next Major Version**, as it will use the latest compatible version of the dependency that can be detected in the repository. Then click **Add Package**.

Lastly, select the `FaceLiveness` product and click **Add Package**.

### Step 3. Request camera permissions

FaceLivenessDetectorView requires access to the camera on the user's device in order to perform the Face Liveness check. Before displaying FaceLivenessDetectorView, prompt the user to grant camera permission. Please follow these guides for guidelines around requesting camera permission [iOS Human Interface Guidelines | Accessing private data](https://developer.apple.com/design/human-interface-guidelines/patterns/accessing-private-data/).

### Step 4. Add FaceLivenessDetectorView

```swift
import SwiftUI
import FaceLiveness

struct MyView: View { 
  @State private var isPresentingLiveness = true

  var body: some View { 
    FaceLivenessDetectorView(
      sessionID: <session ID>,
      region: <region>,
      isPresented: $isPresentingLiveness,
      onCompletion: { result in
        switch result {
        case .success: 
          // ...
        case .failure(let error):
          // ...
        default:
          // ...
        }
      }
    )
  }
}
```
  </Tabs.Panel>
</Tabs.Container>
